/*
 * $Id: fsm.c,v 1.9 2005-12-05 15:11:29 bacon Exp $
 */

#include <xp/utl/fsm.h>
#include <xp/bas/memory.h>

xp_fsm_t* xp_fsm_open (xp_fsm_t* fsm)
{
	if (fsm == XP_NULL) {
		fsm = (xp_fsm_t*)xp_malloc (xp_sizeof(xp_fsm_t));
		if (fsm == XP_NULL) return XP_NULL;
		fsm->__dynamic = xp_true;
	}
	else fsm->__dynamic = xp_false;

	fsm->errnum = XP_FSM_ENOERR;
	fsm->confirmer = XP_NULL;
	fsm->confirmer_arg = XP_NULL;
	return fsm;
}

void xp_fsm_close (xp_fsm_t* fsm)
{
	if (fsm->__dynamic) xp_free (fsm);
}

void xp_fsm_attach_confirmer (
	xp_fsm_t* fsm, xp_fsm_confirmer_t confirmer, void* arg)
{
	fsm->confirmer = confirmer;
	fsm->confirmer_arg = arg;
}

void xp_fsm_detach_confirmer (xp_fsm_t* fsm)
{
	fsm->confirmer = XP_NULL;
	fsm->confirmer_arg = XP_NULL;
}

int xp_fsm_errnum (xp_fsm_t* fsm)
{
	return fsm->errnum;
}

const xp_char_t* xp_fsm_errstr (xp_fsm_t* fsm)
{
	static const xp_char_t* __errstr[] =
	{
		XP_TEXT("no error"),
		XP_TEXT("out of memory"),
		XP_TEXT("invalid data"),
		XP_TEXT("access denined"),
		XP_TEXT("file/directory exists"),
		XP_TEXT("no source"),
		XP_TEXT("same file"),
		XP_TEXT("failed to rename a file"),
		XP_TEXT("failed to unlink a file"),
		XP_TEXT("failed to create a directory"),
		XP_TEXT("unknown error")
	};

	return __errstr[
		(fsm->errnum < 0 || fsm->errnum >= xp_countof(__errstr))? 
		xp_countof(__errstr) - 1: fsm->errnum];

}
